﻿using FB.Enums;
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Linq.Expressions;
using System.Security.Cryptography;
using System.Text;
using System.Web.Mvc;
using System.Web.Mvc.Html;
using System.Web.Security;

namespace FB.Extensions
{
    public static class ICollectionExtensions
    {
        public static bool IsNullOrEmpty(this ICollection collection)
        {
            return !(collection != null && collection.Count > 0);
        }
    }


    public static class StringExtensions
    {
        public static string GetValueOrDefault(this string Value, string DefaultValue)
        {
            return string.IsNullOrEmpty(Value) ? DefaultValue : Value;
        }


        public static string EnhancedSubString(this string s, int startIndex, int length)
        {
            return System.Text.Encoding.Default.GetString(Encoding.Default.GetBytes(s), startIndex, length);
        }


        public static int EnhancedCount(this string s)
        {
            return System.Text.Encoding.Default.GetByteCount(s);
        }


        public static string Decrypt(this string TextToBeDecrypted, string Password)
        {
            RijndaelManaged RijndaelCipher = new RijndaelManaged();

            string DecryptedData;

            try
            {
                byte[] EncryptedData = Convert.FromBase64String(TextToBeDecrypted);

                byte[] Salt = Encoding.ASCII.GetBytes(Password.Length.ToString());
                //Making of the key for decryption
                PasswordDeriveBytes SecretKey = new PasswordDeriveBytes(Password, Salt);
                //Creates a symmetric Rijndael decryptor object.
                ICryptoTransform Decryptor = RijndaelCipher.CreateDecryptor(SecretKey.GetBytes(32), SecretKey.GetBytes(16));

                MemoryStream memoryStream = new MemoryStream(EncryptedData);
                //Defines the cryptographics stream for decryption.THe stream contains decrpted data
                CryptoStream cryptoStream = new CryptoStream(memoryStream, Decryptor, CryptoStreamMode.Read);

                byte[] PlainText = new byte[EncryptedData.Length];
                int DecryptedCount = cryptoStream.Read(PlainText, 0, PlainText.Length);
                memoryStream.Close();
                cryptoStream.Close();

                //Converting to string
                DecryptedData = Encoding.Unicode.GetString(PlainText, 0, DecryptedCount);
            }
            catch
            {
                DecryptedData = TextToBeDecrypted;
            }
            return DecryptedData;
        }


        public static string Encrypt(this string TextToBeEncrypted, string Password)
        {
            RijndaelManaged RijndaelCipher = new RijndaelManaged();
            byte[] PlainText = System.Text.Encoding.Unicode.GetBytes(TextToBeEncrypted);
            byte[] Salt = Encoding.ASCII.GetBytes(Password.Length.ToString());
            PasswordDeriveBytes SecretKey = new PasswordDeriveBytes(Password, Salt);
            //Creates a symmetric encryptor object. 
            ICryptoTransform Encryptor = RijndaelCipher.CreateEncryptor(SecretKey.GetBytes(32), SecretKey.GetBytes(16));
            MemoryStream memoryStream = new MemoryStream();
            //Defines a stream that links data streams to cryptographic transformations
            CryptoStream cryptoStream = new CryptoStream(memoryStream, Encryptor, CryptoStreamMode.Write);
            cryptoStream.Write(PlainText, 0, PlainText.Length);
            //Writes the final state and clears the buffer
            cryptoStream.FlushFinalBlock();
            byte[] CipherBytes = memoryStream.ToArray();
            memoryStream.Close();
            cryptoStream.Close();
            string EncryptedData = Convert.ToBase64String(CipherBytes);

            return EncryptedData;
        }

    }





    public static class HtmlExtensions
    {

        public static MvcHtmlString DropDownListForYear(this HtmlHelper helper, string name, int startYear)
        {
            return DropDownListForYear(helper, name, startYear, null, null);
        }
        public static MvcHtmlString DropDownListForYear(this HtmlHelper helper, string name, int startYear, string optionLabel)
        {
            return DropDownListForYear(helper, name, startYear, optionLabel, null);
        }
        public static MvcHtmlString DropDownListForYear(this HtmlHelper helper, string name, int startYear, string optionLabel, Object htmlAttributes)
        {
            var years = new List<SelectListItem>();
            for (var y = DateTime.Today.Year; y >= startYear; y--)
            {
                years.Add(new SelectListItem { Text = y.ToString(), Value = y.ToString() });
            }

            return helper.DropDownList(name, years, optionLabel, htmlAttributes);
        }



        public static MvcHtmlString DropDownListForMonth(this HtmlHelper helper, string name)
        {
            return DropDownListForMonth(helper, name, null, null);
        }
        public static MvcHtmlString DropDownListForMonth(this HtmlHelper helper, string name, string optionLabel)
        {
            return DropDownListForMonth(helper, name, optionLabel, null);
        }
        public static MvcHtmlString DropDownListForMonth(this HtmlHelper helper, string name, string optionLabel, Object htmlAttributes)
        {
            var months = new List<SelectListItem>();
            for (var m = 1; m <= 12; m++)
            {
                months.Add(new SelectListItem { Text = m.ToString(), Value = m.ToString(), Selected = (m == DateTime.Today.Month) });
            }

            return helper.DropDownList(name, months, optionLabel, htmlAttributes);
        }


        public static string LabelTextFor<TModel, TProperty>(this HtmlHelper<TModel> helper, Expression<Func<TModel, TProperty>> expression)
        {
            var metadata = ModelMetadata.FromLambdaExpression<TModel, TProperty>(expression, helper.ViewData);
            var result = metadata.DisplayName ?? string.Empty;
            if (metadata.IsRequired) result = "*" + result;
            return result;
        }

        public static MvcHtmlString DisplayNullablePrice(this HtmlHelper htmlHelper, decimal? val, string Format)
        {
            return MvcHtmlString.Create(val.HasValue ? val.Value.ToString(Format) : "-");
        }

        public static MvcHtmlString DisplayNullableDate(this HtmlHelper htmlHelper, DateTime? datetime, string Format = null)
        {
            return MvcHtmlString.Create(datetime.HasValue ? datetime.Value.ToString(Format ?? FB.Helpers.AppSettingsBase.DefaultDateFormat) : "-");
        }

        public static MvcHtmlString DisplayNullableDatetime(this HtmlHelper htmlHelper, DateTime? datetime, string Format = null)
        {
            return MvcHtmlString.Create(datetime.HasValue ? datetime.Value.ToString(Format ?? FB.Helpers.AppSettingsBase.DefaultDateTimeFormat) : "-");
        }

        public static MvcHtmlString ApplyBR(this HtmlHelper htmlHelper, string text)
        {
            if (string.IsNullOrEmpty(text))
                return MvcHtmlString.Create(text);
            else
            {
                StringBuilder builder = new StringBuilder();
                string[] lines = text.Split('\n');
                for (int i = 0; i < lines.Length; i++)
                {
                    if (i > 0)
                        builder.Append("<br/>");
                    builder.Append(System.Web.HttpUtility.HtmlEncode(lines[i]));
                }
                return MvcHtmlString.Create("<div id='Size' style='width:500px; word-wrap:break-word;overflow:hidden'>"+builder.ToString()+"</div>");
            }
        }

        public static MvcHtmlString formatCash(this HtmlHelper htmlHelper, string text)
        {
            if (string.IsNullOrEmpty(text))
                return MvcHtmlString.Create(text);
            else
            {
                StringBuilder builder = new StringBuilder();
                string newStr = string.Empty;
                System.Text.RegularExpressions.Regex reg = new System.Text.RegularExpressions.Regex(@"(\d+?)(\d{3})*(\.\d+|$)");
                System.Text.RegularExpressions.Match m = reg.Match(text);
                newStr += m.Groups[1].Value;
                for (int i = 0; i < m.Groups[2].Captures.Count; i++)
                {
                    newStr += "," + m.Groups[2].Captures[i].Value;
                }
                newStr += m.Groups[3].Value;
                builder.Append(System.Web.HttpUtility.HtmlEncode(newStr));
                return MvcHtmlString.Create(builder.ToString());
            }
        }
        

    }


}
